using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI;
using System.Data.OleDb;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Xml.Linq;
using System.Linq;
using RemoteUpdate;
using cn.edu.suda.sumcu.iot;
using Easily._02_Form._01_frmCtrlConfig;
using AHL_GEC;
using WeifenLuo.WinFormsUI.Docking;
using Easily._02_Form.KimiAI;

namespace Easily
{
    public partial class MDIParentFrame : Form
    {
        #region MDIParentFrame类的字段
        ///==============================================================================
        #region 定义编程方式、程序类型的枚举
        /// <summary>当前的编程方式</summary>
        public enum CompileDocumentType
        {
            /// <summary>图形化编程</summary>
            CompileGraphics,
            /// <summary>C语言编程</summary>
            CompileCode,
            /// <summary>无</summary>
            NULL,
        }

        /// <summary>程序类型</summary>
        public enum ProgrammerType
        {
            /// <summary>图形化主程序</summary>
            GraphicMain,
            /// <summary>图形化子程序</summary>
            GraphicSub,
            /// <summary>无</summary>
            NULL,
        }

        /// <summary>程序类型</summary>
        public enum SubFuncType
        {
            /// <summary>普通子程序</summary>
            GeneralSubFunc,
            /// <summary>中断子程序</summary>
            IntSubFunc,
            /// <summary>无</summary>
            NULL,
        }
        #endregion

        #region 定义与串口通信相关的成员变量
        // LayoutKind.Sequential用于强制将成员按其出现的顺序进行顺序布局,字符串转换成ANSI字符串，Pack表示1字节对齐
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        //与终端握手的数据类型
        public struct shakeData
        {
            // SizeConst用来定义数组大小
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            public byte[] uecomType;          //通信模组类型
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public byte[] mcuType;            //MCU类型
            public uint uStartAds;            //User程序起始地址
            public uint uCodeSize;            //User程序总代码大小
            public uint replaceNum;           //替换更新最大字节
            public uint reserveNum;           //保留更新最大字节（不等于0意味着有User程序）
        }
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct newshakeData
        {
            // SizeConst用来定义数组大小
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            public byte[] uecomType;          //通信模组类型
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] mcuType;            //MCU类型
            public uint uStartAds;            //User程序起始地址
            public uint uCodeSize;            //User程序总代码大小
            public uint replaceNum;           //替换更新最大字节
            public uint reserveNum;           //保留更新最大字节（不等于0意味着有User程序）
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public byte[] BIOSVersion;            //BIOS版本号
        }

        //【20230401】新增芯片详细信息
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct new2shakeData
        {
            // SizeConst用来定义数组大小
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            public byte[] uecomType;          //通信模组类型
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            public byte[] mcuType;            //MCU类型
            public uint uStartAds;            //User程序起始地址
            public uint uCodeSize;            //User程序总代码大小
            public uint replaceNum;           //替换更新最大字节
            public uint reserveNum;           //保留更新最大字节（不等于0意味着有User程序）
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            public byte[] BIOSVersion;            //BIOS版本号
            public uint RAMStart;                //RAM起始地址
            public uint RAMLength;               //RAM长度
            public uint FlashStart;              //Flash起始地址
            public uint FlashLength;             //Flash长度
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] coreType;             //内核类型
            public uint mcuSectSize;             //mcu扇区大小
            public uint RTOSSize;             //操作系统空间大小
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte[] RTType;             //内核类型
            public uint RAMUserStart;             //RAM空间User的起始地址
            public uint SystemClock;             //RAM空间User的起始地址
        }
        private new2shakeData new2shakedata;
        private newshakeData newshakedata;
        private shakeData shakedata;          //与终端握手的成员变量
        private string uecomType;             //通信模组类型
        private uint uStartAds;               //User程序起始地址
        private uint uCodeSize;               //User程序总代码大小
        private uint replaceNum;              //替换更新最大字节
        private uint reserveNum;              //保留更新最大字节（不等于0意味着有User程序）
        private byte overallStyle;            //整体更新方式

        public EMUART emuart = new EMUART(); //与串口通信的类对象
        private Hex_old hex_old = new Hex_old(); //（VA.10版本之前）更新程序Hex对象
        private Hex hex = new Hex();             //保存Hex文件信息
        private Update update;                   //保存更新变量
        private Update_old update_old; //（VA.10版本之前）更新类对象，保存更新所使用的帧结构体与方法

        //【4.07 1/4】创建进程对象
        public Process SerialPort = null;
        #endregion

        #region 子窗体实例
        /// <summary>图标控件箱窗口</summary>
        public frmIconBox IconBoxOfForm;
        /// <summary>对应的C代码窗口</summary>
        public frmGraphicCode CodeOfForm;
        /// <summary>信息输出窗口窗口</summary>
        public frmConsole ConsoleForm;
        /// <summary>图形化编程面板</summary>
        public frmGraphicProgrammer GraphicProgrammerOfForm;
        /// <summary>
        /// [2021/3/11]配置窗体
        /// </summary>
        public frmConfigHardCon formHard;
        #endregion

        /// <summary>MCU类型</summary>
        public string mcuType = "STM32L431BIOS";
        /// <summary>适配的开发环境</summary>
        public string textIDE = "KDS";
        /// <summary>默认未处于高级模式，即处于图形化模式</summary>
        public bool IsAdvanceMode = false;
        /// <summary>当前工程文件路径</summary>                                         
        public string ProjectPath = "";
        /// <summary>当前工程名</summary>
        public string ProjectName = "";
        //用于实现复制、剪切、删除和粘贴功能
        public delegate void MyValueChanged(string context);//20160317
        public event MyValueChanged OnMyValueChanged;//20160317
        public string contextMenu = string.Empty;//20160317
        public string ContextString
        {
            get { return contextMenu; }
            set
            {
                if (value != contextMenu)
                {
                    WhenMyValueChange((string)value);
                }

            }
        }
        //芯片信息
        public string strMCUType;
        //private string strMCUName;
        //private string strCCompile;
        //private string strAssem;
        //private string strLinkerTool;
        //private string strObjcopyTool;
        //private string strObjdumpTool;
        //private string strMakeTool;
        //private string strArTool;
        //private string strNmTool;
        //private string strHWBase;
        //private string RAMStartAddr;
        //private string RAMSize;
        //private string FlashStartAddr;
        //private string FlashSize;
        //private string INTVectorStartAddr;
        //private string PageStartAddr;
        //private string PageSize;
        //private string PageCount;
        //private string StakAddr;
        //private string FlashEraseStartAddr;
        //private string CodeStartAddr;
        //private string CodeSize;

        /// <summary>当前的编程方式</summary>
        private CompileDocumentType CompileType;
        /// <summary>当前活跃的图形化编程设计面板</summary>
        public frmGraphicProgrammer ActivedrmGraphicFlow;
        //[2021/4/13]hsc-添加金葫芦IDE中的串口更新窗体
        public frm_NBUpdate mfrm_NBUpdate;    //串口更新窗体
        /// <summary>保存图形化编程面板窗口列表</summary>
        public ArrayList frmGraphicFlowArray = new ArrayList();
        /// <summary>程序信息</summary>
        private bool AlreadyCreateProgrammer;
        /// <summary>是否修改了程序</summary>
        public bool ModifyProgrammer;
        /// <summary>背景图片</summary>
        private PictureBox bg = new PictureBox();

        /// <summary>当前鼠标操作是正常操作还是拖动工作区操作</summary>
        /// <summary>true:拖动工作区操作</summary>
        /// <summary>false:正常操作</summary>
        public bool MoveOrComCursor;

        /// <summary>复制或者剪切的控件类型</summary>
        private LineLinkIconType CopyIconType = LineLinkIconType.NULL;
        /// <summary>复制或者剪切的控件序号下标</summary>
        private int CopyIconDbNum;
        /// <summary>复制或者剪切的控件名称</summary>
        private string CopyIconName;
        /// <summary>复制或者剪切的控件的代码</summary>
        private string[] CopyIconCode = new string[4];
        //private string CopyIconCode;//20160318修改
        /// <summary>复制或者剪切的控件的中心点X坐标</summary>
        private int CopyIconMidPX;
        /// <summary>复制或者剪切的控件的中心点Y坐标</summary>
        private int CopyIconMidPY;
        /// <summary>复制或者剪切的通用控件的类型</summary>
        public GeneralIcon.TypeOfGeneralIcon CopyIconGeneralIconType;

        // 定义委托事件，用于输出编译信息等
        public delegate void DelReadStdOutput(string result);
        public delegate void DelReadErrOutput(string result);
        public event DelReadStdOutput ReadStdOutput;
        public event DelReadErrOutput ReadErrOutput;

        #endregion

        #region MDIParentFrame类的方法
        ///==============================================================================
        //MDIParentFrame类的构造函数
        public MDIParentFrame()
        {
            try
            {
                string fileName = string.Empty;
                //设置窗体的属性
                InitializeComponent();
                this.WindowState = FormWindowState.Maximized;
                this.dockPanel1.DocumentStyle = DocumentStyle.DockingSdi;
                //dockPanel1.ActiveContentChanged += DockPanel1_ActiveContentChanged;
                ///// <summary>图标控件箱窗口</summary>
                //IconBoxOfForm.
                ///// <summary>对应的C代码窗口</summary>
                //public frmGraphicCode CodeOfForm;
                ///// <summary>信息输出窗口窗口</summary>
                //public frmConsole ConsoleForm;
                ///// <summary>图形化编程面板</summary>
                //public frmGraphicProgrammer GraphicProgrammerOfForm;
                AlreadyCreateProgrammer = false;
                //ProjectPath = string.Empty;
                //ProjectName = string.Empty;
                ModifyProgrammer = false;
                MoveOrComCursor = false;
                //MainFormHandle = this.Handle.ToInt32();//记录主窗体句柄   
                //注册容器中内容发生变化时的事件
                this.dockPanel1.ActiveContentChanged += new EventHandler(dockPanel1_ActiveContentChanged);
                this.dockPanel1.ActiveDocumentChanged += new EventHandler(dockPanel1_ActiveDocumentChanged);
                /// 获取启动了应用程序的可执行文件的路径 【GZF 2015-1-21 添加】 ///
                //string tempStr = System.Windows.Forms.Application.StartupPath;
                //programmersPath = tempStr.Substring(0, tempStr.LastIndexOf("bin")) + "stand_alone programmers";
                /// 同时将编译器的路径写入用户环境变量中 【GZF 2015-5-24】 ///
                //GdsEnviromentPath.SetUserPathAfter(Directory.GetParent(Application.StartupPath) + @"\armCompileFile\bin");               
                //JFASHINISET(); //设置JFlash.ini配置文件20160418  


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }



        ///==============================================================================
        #endregion

        #region MDIParentFrame类的事件
        /// <summary>
        /// MDIParentFrame主窗体加载事件
        /// 功能概要：注册复制粘贴事件；从数据库中导出图标信息和mcu信息
        /// </summary>
        private void MDIParentFrame_Load(object sender, EventArgs e)
        {
            Globaldefine.FrmParent = this;

            Globaldefine.exePath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

            //注册事件
            ReadStdOutput += new DelReadStdOutput(ReadStdOutputAction);
            ReadErrOutput += new DelReadErrOutput(ReadErrOutputAction);
            OnMyValueChanged += new MyValueChanged(afterMyValueChanged);//20160317用于复制、粘贴等            
            Globaldefine.loadConfig = new LoadConfig();

            ////打开工程时触发的事件
            //this.toolStripMenuItemOpenMain.Click += new System.EventHandler(this.openProgrammer);
            //this.openToolStripButton.Click += new System.EventHandler(this.openProgrammer);

            //读取工程的配置文件信息
            if (!Globaldefine.loadConfig.LoadIconBoxInfoFromIconBoxBase())
            {
                MessageBox.Show("读取配置文件Config.json失败!");
                this.Close();
                this.Dispose();
                return;
            }
            strMCUType = Globaldefine.loadConfig.config.mcu_config.type;
        }
        /// <summary>
        /// 容器的内容发生改变时触发，如被拖动等
        /// 功能概要：若有需要，则提前显示代码，作用不是很大
        /// </summary>
        private void dockPanel1_ActiveContentChanged(object sender, EventArgs e)
        {
            try
            {
                if (CompileType == CompileDocumentType.CompileGraphics)
                {
                    if (ActivedrmGraphicFlow != null)
                    {
                        if (CodeOfForm != null && CodeOfForm.IsActivated)
                        {
                            ActivedrmGraphicFlow.CreateCode();//当此句打开，更早形成代码20151220
                        } //否则在dockPanel1_ActiveDocumentChanged事件中才形成代码
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        /// <summary>
        /// 控件树形图中的元素发生改变时触发本事件
        /// 功能概要：
        /// </summary>
        private void dockPanel1_ActiveDocumentChanged(object sender, EventArgs e)
        {
            try
            {
                //树形视图中添加删除子程序控件
                if (CompileType == CompileDocumentType.CompileGraphics)
                {
                    //记录当前活跃的面板设计窗口,并生成窗口的代码
                    foreach (frmGraphicProgrammer dc in frmGraphicFlowArray)
                    {
                        if (dc.IsActivated)
                        {
                            ActivedrmGraphicFlow = dc;
                            ActivedrmGraphicFlow.CreateCode(); //打开一个工程的代码执行此句 20151220
                                                               //其功能是重设面板图标大小、位置坐标和连接点位置等
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        /// <summary>
        /// 单击“新建”按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void newToolStripButton_Click(object sender, EventArgs e)
        {
            if (!CreateProgrammer(ProgrammerType.GraphicMain))
            {
                MessageBox.Show("创建主程序失败!");
            }
        }

        /// <summary>
        ///单击“新建”图形化主程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItemGraphicMain_Click(object sender, EventArgs e)
        {
            if (!CreateProgrammer(ProgrammerType.GraphicMain))
            {
                MessageBox.Show("创建主程序失败!");
            }
        }
        //单击“工具”=》“修复BIOS”按钮
        private void 修复BIOSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string outData = "";
            string showMsg = "";
            tlbl_status.Text = "              正 在 下 载，请 稍 候...！！！";
            string strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
            if (!File.Exists(strMakefileHexPath + @"\BIOS.hex"))
            {
                MessageBox.Show("修复失败：BIOS程序被删除");
                return;
            }
            //this.Refresh(); //让上面的提示，立即显示qingshaoh
            using (Process p = new Process())
            {
                //Process类有一个StartInfo属性，这个是ProcessStartInfo类，包括了一些属性和方法，                
                p.StartInfo.FileName = "jlink";      //设定程序名   
                p.StartInfo.UseShellExecute = false;//关闭Shell的使用
                p.StartInfo.CreateNoWindow = true;  //设置不显示窗口                
                p.StartInfo.RedirectStandardInput = true;  //重定向标准输入                
                p.StartInfo.RedirectStandardOutput = true; //重定向标准输出                
                p.StartInfo.RedirectStandardError = true;  //重定向错误输出  
                p.OutputDataReceived += (sender2, e2) =>
                {
                    if (e2.Data != null)
                        outData += e2.Data.ToString() + "\r\n";
                };

                p.Start();
                p.BeginOutputReadLine();
                //烧录程序，并运行
                p.StandardInput.WriteLine("device " + mcuType);
                p.StandardInput.WriteLine("s");
                p.StandardInput.WriteLine();
                p.StandardInput.WriteLine("loadfile " + Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\BIOS.hex");
                p.StandardInput.WriteLine("r");
                p.StandardInput.WriteLine("g");
                p.StandardInput.WriteLine("qc");

                p.WaitForExit();   //等待程序退出

                if (outData == "")
                    showMsg = "修复失败：无信息返回！";
                else if (outData.Contains("Connecting to J-Link via USB...FAILED"))
                    showMsg = "修复失败：未连接SWD写入器，请连接后重试！";
                else if (outData.Contains("Writing target memory failed"))
                    showMsg = "修复失败：已连接SWD写入器，但未连接设备或选择的设备型号有误！";
                else
                    showMsg = "修复成功！";

                tlbl_status.Text = showMsg;
                MessageBox.Show(showMsg);

                p.Close();//结束进程------20151018修改
                p.Dispose();
            }
        }


        //打开图形化工程和KDS工程
        //高级模式下既能打开KDS工程，也可打开图形化工程
        //但打开图形化工程时，应该已经在编辑状态
        private void openProgrammer(object sender, EventArgs e)
        {
            if (!OpenProgrammer(ProgrammerType.GraphicMain, false))
            {
                MessageBox.Show("打开主程序失败!");
            }
        }

        /// <summary>
        /// 触发条件：在控件上右击，并选择右击菜单的某一项
        /// 函数功能：
        /// 修改时间：20160317
        /// </summary>
        private void afterMyValueChanged(string text)
        {

            switch (text)
            {
                case "剪切":
                    cutToolStripMenuItem_Click(null, null);
                    break;
                case "复制":
                    copyToolStripMenuItem_Click(null, null);
                    break;
                case "粘贴":
                    pasteToolStripMenuItem_Click(null, null);
                    break;
                case "删除":
                    toolStripMenuItemDelete_Click(null, null);
                    break;
                default:
                    break;
            }

        }

        //复制或剪切所选控件
        public void CopySelectedIcon(bool flag)
        {
            frmGraphicProgrammer content = (frmGraphicProgrammer)(dockPanel1.ActiveDocument);
            if (content != null)
                content.CopyIcon(ref this.CopyIconType, ref this.CopyIconDbNum, ref this.CopyIconName,
                    ref this.CopyIconMidPX, ref this.CopyIconMidPY, ref this.CopyIconCode, flag);
        }

        //粘帖所选控件
        public void PasteSelectedIcon()
        {
            frmGraphicProgrammer content = (frmGraphicProgrammer)(dockPanel1.ActiveDocument);
            if (content != null)
                content.PasteIcon(this.CopyIconType, this.CopyIconDbNum,
                this.CopyIconName, this.CopyIconMidPX, this.CopyIconMidPY, this.CopyIconCode);
        }

        //删除所选控件
        public void DeleteSelectedIcon()
        {
            frmGraphicProgrammer content = (frmGraphicProgrammer)(dockPanel1.ActiveDocument);
            if (content != null)
                content.DeleteIcon();
        }

        //保存工程
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveProgrammerFile();
        }

        //工程另存为
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProjectPath = "";
            SaveProgrammerFile();
        }

        //关闭所有文件
        private void toolStripMenuItemClosaAll_Click(object sender, EventArgs e)
        {

            CloseAllProgrammer();
            //[2021/1/31] 未有工程前不可使用配置终端 此处关闭工程因此不可以打开
            this.配置硬件ToolStripMenuItem.Enabled = false;
            //[2021/3/9] 未有工程前不可使用串口更新 此处关闭工程因此不可以打开
            this.toolStripMenuItemWrite2MCU.Enabled = false;
            this.panel1.Visible = true;
            this.panel1.Visible = false; //关闭启动时的图片
            //this.panel1.BackgroundImage = global::IDE_For_MCUs.Properties.Resources.Clip3;
        }

        //退出
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
            this.Dispose();
            Application.Exit();
        }

        //剪切图标控件操作
        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Globaldefine.FrmParent.IsAdvanceMode)
            {
                string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
                switch (s)
                {
                    case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_cut.PerformClick(); break;
                    case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_cut.PerformClick(); break;
                    case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_cut.PerformClick(); break;
                    default: break;
                }
            }
            else
            {
                if (this.CompileType == CompileDocumentType.CompileGraphics)
                {
                    CopySelectedIcon(true);
                    ModifyProgrammer = true;
                }
            }
        }

        //复制图标控件操作
        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Globaldefine.FrmParent.IsAdvanceMode)
            {
                string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
                switch (s)
                {
                    case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_copy.PerformClick(); break;
                    case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_copy.PerformClick(); break;
                    case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_copy.PerformClick(); break;
                    default: break;
                }
            }
            else
            {
                if (this.CompileType == CompileDocumentType.CompileGraphics)
                {
                    CopySelectedIcon(false);
                    ModifyProgrammer = true;
                }
            }
        }

        //粘贴图标控件操作
        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (Globaldefine.FrmParent.IsAdvanceMode)
            {
                string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
                switch (s)
                {
                    case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_paste.PerformClick(); break;
                    case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_paste.PerformClick(); break;
                    case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_paste.PerformClick(); break;
                    default: break;
                }
            }
            else
            {
                if (this.CompileType == CompileDocumentType.CompileGraphics)
                {
                    PasteSelectedIcon();
                    ModifyProgrammer = true;
                }
            }

        }

        //删除图标控件操作
        private void toolStripMenuItemDelete_Click(object sender, EventArgs e)
        {
            if (Globaldefine.FrmParent.IsAdvanceMode)
            {
                string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
                switch (s)
                {
                    case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_del.PerformClick(); break;
                    case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_del.PerformClick(); break;
                    case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_del.PerformClick(); break;
                    default: break;
                }
            }
            else
            {
                if (this.CompileType == CompileDocumentType.CompileGraphics)
                {
                    DeleteSelectedIcon();
                    ((frmGraphicProgrammer)(this.dockPanel1.ActiveDocument)).CreateCode();
                    ModifyProgrammer = true;
                }
            }

        }
        //点击【进入高级模式】
        private void ToolStripMenuItem_advance_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("进入高级模式之后，可以在图形化拖拽出来的画面基础上进行编写代码。");
            if (ActivedrmGraphicFlow == null || dockPanel1 == null)
                return;
            IsAdvanceMode = !IsAdvanceMode;
            //高级模式下代码可编写
            if (IsAdvanceMode)
            {
                ToolStripMenuItem_advance.Text = "退出高级模式";
                ActivedrmGraphicFlow.IsHidden = true;
                if (IconBoxOfForm != null) IconBoxOfForm.IsHidden = true;
                dockPanel1.DockTopPortion = 0.8;
                if (CodeOfForm != null)
                {
                    //代码可编写
                    CodeOfForm.Show(dockPanel1, DockState.DockTop);
                    CodeOfForm.setReadOnly(false);
                    CodeOfForm.addRightClick();
                }
            }
            //普通模式下代码不可改动
            else
            {
                ToolStripMenuItem_advance.Text = "进入高级模式";
                ActivedrmGraphicFlow.IsHidden = false;
                if (IconBoxOfForm != null) IconBoxOfForm.IsHidden = false;
                dockPanel1.DockRightPortion = 0.3;//曾经是0.36
                if (CodeOfForm != null)
                {
                    CodeOfForm.Show(dockPanel1, DockState.DockRight);
                    CodeOfForm.setReadOnly(true);
                    //CodeOfForm.removeRightClick();
                }
            }
        }
        //点击【搜索】=》【文件中查找】
        private void 文件中查找ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //if (Globaldefine.FrmParent.IsAdvanceMode)
            //{
            string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
            switch (s)
            {
                case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_find.PerformClick(); break;
                case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_find.PerformClick(); break;
                case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_find.PerformClick(); break;
                default: break;
            }
            //}
        }
        //点击【搜索】=》【文件中替换】
        private void 文件中替换ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Globaldefine.FrmParent.IsAdvanceMode)
            {
                string s = Globaldefine.FrmParent.CodeOfForm.tctr_code.SelectedTab.Text;
                switch (s)
                {
                    case "main.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_main.CM_replace.PerformClick(); break;
                    case "isr.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_isr.CM_replace.PerformClick(); break;
                    case "includes.c": Globaldefine.FrmParent.CodeOfForm.tboxMenu_includes.CM_replace.PerformClick(); break;
                    default: break;
                }
            }
            //[2021/4/14]-hsc只有出于高级模式下才可以使用文件中替换
            //应给予用户提示
            else
            {
                MessageBox.Show("请切换到高级模式下，再使用本功能！");
            }
        }
        /// <summary>
        /// 点击“连接终端”按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 连接终端ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtShow("正在与终端UE建立连接...");
            if (!connectGEC())
            {
                MessageBox.Show("与UE通信失败");
                goto ConnectUeExit;
            }
            txtShow("与终端UE连接成功，已获取芯片信息！");

        ConnectUeExit:
            return;
        }
        /// <summary>
        /// 点击“编译程序”按钮
        /// </summary>
        private void toolStripMenuItemCompile_Click(object sender, EventArgs e)
        {
            int i;
            string strBinDir = string.Empty;
            string strIncludeDir = string.Empty;
            string strLibDir = string.Empty;

            if (Globaldefine.FrmParent.ActivedrmGraphicFlow == null)
            {
                MessageBox.Show("请首先打开或新建一个工程，再点击“编译”按钮！");
                return;

            }
            //信息提示
            tlbl_status.Text = "              编 译 中, 请 稍 候...！！！ ";
            this.Refresh(); //让上面的提示，立即显示。
            string strPath = string.Empty;
            if (strMCUType == "32位MCU")      //若目标设备为32位MCU
            {
                this.SaveProgrammerFile();
                //==========================主程序创建滞后保证编译后的窗口为主程序===============================================

                //[20181115]

                for (i = 0; i < frmGraphicFlowArray.Count; i++)
                {
                    if (((frmGraphicProgrammer)frmGraphicFlowArray[i]).ProgrammerType == ProgrammerDocumentType.MainFun)
                    {
                        break;
                    }
                }
                ((frmGraphicProgrammer)frmGraphicFlowArray[i]).Activate();//20160323 激活主程序，保存图形化主程序界面窗口
                //生成主程序代码并保存
                if (i < frmGraphicFlowArray.Count)//【GZF 生成程序源代码 2015-5-13】
                {
                    //((frmGraphicProgrammer)frmGraphicFlowArray[i]).SaveCodeOfFunc(strPath + "Source");
                    ((frmGraphicProgrammer)frmGraphicFlowArray[i]).SaveCodeOfFunc(Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source\07_AppPrg");
                }
                //编译工程
                ConsoleForm.txt_info.Focus();
                Compile32Programmer();
            }
        }

        /// <summary>
        /// 点击【下载】=》【swd烧录】
        /// 功能概要：提供给toolstripMenums动态绑定的事件函数 
        /// </summary>
        public void dynamicTSM_click(object sender, EventArgs exeName)
        {
            string outData = "";
            string showMsg = "";
            tlbl_status.Text = "              正 在 下 载，请 稍 候...！！！";
            string strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
            if (!File.Exists(strMakefileHexPath + @"\easily.hex"))
                toolStripMenuItemCompile_Click(sender, exeName);
            //this.Refresh(); //让上面的提示，立即显示qingshaoh
            using (Process p = new Process())
            {
                //Process类有一个StartInfo属性，这个是ProcessStartInfo类，包括了一些属性和方法，                
                p.StartInfo.FileName = "jlink";      //设定程序名   
                p.StartInfo.UseShellExecute = false;//关闭Shell的使用
                p.StartInfo.CreateNoWindow = true;  //设置不显示窗口                
                p.StartInfo.RedirectStandardInput = true;  //重定向标准输入                
                p.StartInfo.RedirectStandardOutput = true; //重定向标准输出                
                p.StartInfo.RedirectStandardError = true;  //重定向错误输出  
                p.OutputDataReceived += (sender2, e2) =>
                {
                    if (e2.Data != null)
                        outData += e2.Data.ToString() + "\r\n";
                };

                p.Start();
                p.BeginOutputReadLine();
                //烧录程序，并运行
                p.StandardInput.WriteLine("device " + mcuType);
                p.StandardInput.WriteLine("s");
                p.StandardInput.WriteLine();
                p.StandardInput.WriteLine("loadfile " + Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\easily.hex");
                p.StandardInput.WriteLine("r");
                p.StandardInput.WriteLine("g");
                p.StandardInput.WriteLine("qc");

                p.WaitForExit();   //等待程序退出

                if (outData == "")
                    showMsg = "下载失败：无信息返回！";
                else if (outData.Contains("Connecting to J-Link via USB...FAILED"))
                    showMsg = "下载失败：未连接SWD写入器，请连接后重试！";
                else if (outData.Contains("Writing target memory failed"))
                    showMsg = "下载失败：已连接SWD写入器，但未连接设备或选择的设备型号有误！";
                else
                    showMsg = "下载成功！";

                tlbl_status.Text = showMsg;
                MessageBox.Show(showMsg);

                p.Close();//结束进程------20151018修改
                p.Dispose();
            }
        }
        uint softVersion = 0;

        //点击【下载】=》【串口调试】
        private void 串口调试ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtShow("正在与终端UE建立连接...");
            if (!connectGEC())
            {
                MessageBox.Show("与UE通信失败");
                goto UartDebugExit;
            }
            txtShow("与终端UE连接成功！");
        UartDebugExit:
            return;
        }


        /// <summary>
        /// 触发条件：保存图标按钮实现
        /// 功能概要：保存整个工程(.prj文件)
        /// </summary>
        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            //高级模式下只能保存为KDS工程
            if (IsAdvanceMode == true)
            {
                string path = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source\07_AppPrg";
                //存储g更改的程序代码
                Globaldefine.FrmParent.CodeOfForm.text_main.SaveFile(path + @"\main.c");
                Globaldefine.FrmParent.CodeOfForm.text_isr.SaveFile(path + @"\isr.c");
                Globaldefine.FrmParent.CodeOfForm.text_includes.SaveFile(path + @"\includes.h");
                //导出为KDS工程
                toolStripMenuItemLoadCFile_Click(new object(), new EventArgs());

            }
            //普通模式
            else
            {
                //保存工程文件
                SaveProgrammerFile();
            }


        }

        /// <summary>
        /// 触发条件：点击“导出为KDS工程”按钮
        /// 功能概要：将主程序以KDS工程的形式导出到指定位置
        /// </summary>
        private void toolStripMenuItemLoadCFile_Click(object sender, EventArgs e)
        {
            int i;
            for (i = 0; i < frmGraphicFlowArray.Count; i++)
            {
                if (((frmGraphicProgrammer)(frmGraphicFlowArray[i])).ProgrammerType == ProgrammerDocumentType.MainFun)
                {
                    break;
                }
            }

            if (i < frmGraphicFlowArray.Count)
            {
                string strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
                FolderBrowserDialog fPathDialog = new FolderBrowserDialog();
                fPathDialog.Description = "导出KDS工程到文件夹：";
                if (fPathDialog.ShowDialog(this) == DialogResult.OK)
                {
                    string strPath = fPathDialog.DirectoryPath;
                    strPath += "\\AHL-Project";
                    int index = 1;
                    string sTmp = strPath;
                    while (true)
                    {
                        if (!Directory.Exists(sTmp))
                            break;
                        index++;
                        sTmp = strPath + index.ToString();
                    }
                    strPath = sTmp;
                    //重新生成代码并保存
                    ((frmGraphicProgrammer)frmGraphicFlowArray[i]).SaveCodeOfFunc(strMakefileHexPath + @"\Source\07_AppPrg");

                    Process p = new Process();
                    //Process类有一个StartInfo属性，这个是ProcessStartInfo类，包括了一些属性和方法，
                    //设定程序名
                    p.StartInfo.FileName = "cmd.exe";
                    //关闭Shell的使用
                    p.StartInfo.UseShellExecute = false;
                    //重定向标准输入
                    p.StartInfo.RedirectStandardInput = true;
                    //重定向标准输出
                    p.StartInfo.RedirectStandardOutput = true;
                    //重定向错误输出
                    p.StartInfo.RedirectStandardError = true;
                    //设置不显示窗口
                    p.StartInfo.CreateNoWindow = true;
                    //上面几个属性的设置是比较关键的一步。
                    p.Start();
                    //输入要执行的命令
                    p.StandardInput.WriteLine(strMakefileHexPath.Substring(0, 2));//20160513 取出盘符，并切换到安装盘，在xp下无法直接切换到另一个盘的目录
                    p.StandardInput.WriteLine("cd " + strMakefileHexPath);
                    p.StandardInput.WriteLine("make clean");
                    //string strRstComplier = p.StandardOutput.ReadToEnd();
                    //无限等待关联进程的退出
                    //p.WaitForExit();
                    p.Close();//结束进程------20151018修改
                    p.Dispose();
                    for (int iii = 0; iii < 100; iii++)
                    {
                        if (!File.Exists(strMakefileHexPath + @"\easily.hex"))
                            break;
                        Thread.Sleep(100);
                    }
                    //拷贝工程到指定目录
                    CopyDirectory(Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source", strPath);
                    MessageBox.Show("成功导出KDS工程到路径：" + strPath);
                }
            }
        }

        /// <summary>
        /// 触发条件：点击“帮助”=》“用户文档”按钮
        /// 功能概要：打开用户文档“usebook.txt”，并显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contentsToolStripMenuItem_Click(object sender, EventArgs e)//使用说明事件
        {
            frmusebook Usingbook = new frmusebook();
            Usingbook.Show(dockPanel1);

        }

        /// <summary>
        /// 触发条件：点击“帮助”=》“使用说明”按钮
        /// 功能概要：打开帮助文件“Easily使用说明.docx”
        /// </summary>
        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = Directory.GetParent(Application.StartupPath) + "\\使用说明.docx";//文件地址
            //可以打开任意的文件类型，例如：txt，pdf，chm等文件
            process.StartInfo.Verb = "Open";
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
            process.Start();
        }

        ///==============================================================================
        ///
        // [2021/3/11] 在外面进行配置终端窗口的初始化似乎不合理 现在调整到frmParentMDI的构造函数中
        //frmConfigHardCon formHard = new frmConfigHardCon();
        private void 配置硬件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            formHard = new frmConfigHardCon(false);
            formHard.Show();
        }

        private void toolStripMenuItemWrite2MCU_Click(object sender, EventArgs e)
        {
            

        }

        /// <summary>
        /// 窗口关闭时提示是否保存工程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MDIParentFrame_FormClosing(object sender, FormClosingEventArgs e)
        {
            //当前有工程在
            if (ActivedrmGraphicFlow != null)
            {
                DialogResult result = MessageBox.Show("是否保存本工程文件？", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                if (result == DialogResult.OK)
                {
                    SaveProgrammerFile();
                    e.Cancel = false;  //点击OK   
                }
                //点击取消则直接关闭窗体
                //else
                //{
                //    e.Cancel = true;
                //}
            }
        }

        private void 向串口发送数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //【4.07 4/4】启动独立功能的可执行文件
            //【20210331】
            Add_Internal_Software(ref SerialPort, Path.Combine(Globaldefine.exePath, "Config", "InterConn", "SerialPort", "SerialPort.exe"));
        }
        #endregion

        #region 内部调用函数

        //解析待烧录的hex文件
        bool openHex(string path)
        {
            //（1）变量声明           
            bool retVal = false;
            int flag;
            uint startAdd;            //代码起始地址
            uint codesize;            //代码大小
            string filePath;          //文件路径
            string fileName;          //文件名
            string line;              //Hex文件行数据
            List<hexStruct_old> list; //更新程序对应Hex文件保存变量            
            //（2）如果终端更新程序版本为VA.10之后的版本
            if (softVersion == 2)
            {
                //（2.3）导入解析Hex文件
                flag = hex.loadFile(path);
                if (flag != 0) goto btn_fileopen1_Click_EXIT1;
                //（2.4）获取导入的文件信息
                fileName = hex.getFileName();
                startAdd = hex.getStartAddress();
                codesize = hex.getCodeSize();
                //（2.5）判断导入的Hex文件首地址是否正确
                if (startAdd != uStartAds) goto btn_fileopen1_Click_EXIT3;//地址不符合               
            }
            //（3）如果终端更新程序版本为VA.10及其之前的版本
            else if (softVersion == 1)
            {
                //（3.3）获取文件数据，并显示在文件显示框
                //（2）打开文件
                FileStream fs = new FileStream(path, FileMode.Open);
                if (fs == null)  //文件打开失败
                {
                    MessageBox.Show("Hex文件路径错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return false; ;
                }
                if (fs == null) goto btn_fileopen1_Click_EXIT1;    //文件打开失败
                //fmain.lbl_mainstatus.Text = "运行状态：" + fileName + "文件打开成功，正在读取文件数据...";   //底部提示
                //（3.4）读取数据
                StreamReader sr = new StreamReader(fs);  //读取数据流
                hex_old.clear();  //先清空hex数据，准备接收hex数据
                //this.lst_codeshow1.Items.Clear();    //左侧代码显示区
                //（3.5）遍历hex文件，读出到文本框中
                while (true)
                {
                    line = sr.ReadLine();  //读取1行数据
                    if (line == null) break;  //文件读取错误，退出
                    hex_old.addLine(line);  //获取hex文件行数据有效数据
                    //this.lst_codeshow1.Items.Add(line);     //左侧代码显示区                  
                }
                sr.Close();  //关闭数据流
                fs.Close();
                list = hex_old.getHexList();
                //（3.6）判断读取文件的合法性,如果不合法
                if (list[0].address != 0x6800) goto btn_fileopen1_Click_EXIT3;
            }
            retVal = true;
        //（4）退出区
        //（4.1）退出函数
        btn_fileopen1_Click_EXIT:
            return retVal;

        //（4.2）导入hex文件失败
        btn_fileopen1_Click_EXIT1:
            MessageBox.Show("Hex文件异常!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            goto btn_fileopen1_Click_EXIT;

        //（4.3）未选择Hex文件
        btn_fileopen1_Click_EXIT2:
            goto btn_fileopen1_Click_EXIT;

        //（4.4）导入的Hex文件不合法
        btn_fileopen1_Click_EXIT3:
            MessageBox.Show("Hex文件异常!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            goto btn_fileopen1_Click_EXIT;
        }
        //烧录下载hex文件
        bool downloadHexByUart()
        {
            //（1）变量声明
            bool retVal = false;
            int sum;          //发送总帧数
            int cur;          //当前发送帧号
            byte[] senddata = null;
            byte[] recvdata = null;
            int flag;         //（VA.10之前）更新标志位
            byte[] shake = { (byte)10, (byte)'s', (byte)'h', (byte)'a', (byte)'k', (byte)'e' };  //握手帧
            byte[] startUpdate = { (byte)11, (byte)'u', (byte)'p', (byte)'d', (byte)'a', (byte)'t', (byte)'e' }; //开始更新提示帧
            byte[] zero = new byte[500];
            byte[] bRet = null;
            byte[] data = null;
            byte[] reStartFrame = new byte[3];
            string com = "";    //串口信息
            string sTemp = "";
            byte[] recv = null;//保存串口接收信息
            //（3）重新遍历串口，寻找终端
            //if (emuart._Uartport != null)
            //{
            //    emuart._Uartport.Close();
            //    emuart._Uartport.Dispose();
            //}
            //Thread.Sleep(100);   //等待串口关闭
            Application.DoEvents();     //【20191024】与重新连接部分原理相同
            //if (emuart == null || emuart.haveUE == false)
            //{
            //    emuart = new EMUART();    //每次“重新连接”重新实例化
            //    emuart.findDevice(out com, 115200);  //寻找emuart设备
            //}


            //（4.3)如果找到串口与UE,向设备发送握手帧
            emuart.bufferClear();   //清除接收数组缓冲区
            //（2）如果更新程序版本为VA.10之后的版本
            if (softVersion == 2)
            {
                //（2.1）若未导入Hex文件或串口连接失败则退出（防错用）
                if (hex.getHexList().Count == 0) goto btn_autoupdate1_Click_EXIT1;//未导入Hex文件
                if (emuart == null || emuart.haveUE == false) goto btn_autoupdate1_Click_EXIT2;//串口连接失败
                                                                                               //（2.2）开始更新

                update = new Update(overallStyle, hex.getHexList());  //update初始化
                sum = update.getFrameNum();
                try
                {
                    //fmain.lbl_mainstatus.Text = "运行状态：整体更新开始";   //底部提示
                      
                    //（2.2.1）从update类中取出待发送的数据帧，逐一进行发送
                    while ((senddata = update.getNextFrame()) != null)
                    {
                        cur = update.getNextIndex();
                        //如果是第一帧 提示更新开始
                        if (cur == 0)
                            txtShow("整体更新开始:");     //右侧更新提示区
                        //非最后的更新命令帧，需返回数据
                        if (cur != sum - 1)
                        {
                            //第26帧做特殊处理，防止延迟
                            if (cur == 25)
                            {
                                int aaa = 10;
                            }
                            if (!emuart.send(senddata, out recvdata, 1000, 2)) goto btn_autoupdate1_Click_EXIT5;  //未接收到正确返回信息
                            if (update.updateRecv(recvdata) != 0) goto btn_autoupdate1_Click_EXIT6;  //更新返回帧异常
                            //当前帧数据操作成功，进度条显示更新进度
                            //this.prg_update1.Value = (cur + 1) * 100 / sum;            //进度条显示
                            //this.lbl_progressbar1.Text = (cur + 1) * 100 / sum + "%";  //进度百分比显示
                            //this.prg_update1.Refresh();
                            //成功提示
                            txtShow("当前第" + (cur + 1).ToString() + "/" + sum.ToString() + "帧 ");     //右侧更新提示区  
                        }
                        //最后一帧更新命令帧，仅需发送
                        else
                        {
                            txtShow("当前第" + (cur + 1).ToString() + "/" + sum.ToString() + "帧 ");     //右侧更新提示区  
                            emuart.send(senddata, out recvdata, 0, 1); //令发送等待时间为0 20190516（1/2） 【20210225】处理二次提示 
                            System.Threading.Thread.Sleep(100); //延时100毫秒
                            return true;
                        }
                    }
                    //（2.3）更新成功 
                    goto btn_autoupdate1_Click_EXIT3;
                }
                catch (Exception ex)
                {
                    //fmain.lbl_mainstatus.Text = "运行状态：系统异常退出";   //底部提示
                    //txtShow1("系统异常退出\r\n" + ex + "\r\n");     //右侧更新提示区  
                    goto btn_autoupdate1_Click_EXIT;
                }
            }
            //（3）如果更新程序版本为VA.10及其之前的版本
            else if (softVersion == 1)
            {
                //（3.1）若未导入Hex文件或串口连接失败则退出（防错用）
                flag = 0;
                if (hex_old.getHexList() == null) goto btn_autoupdate1_Click_EXIT1;    //未导入Hex文件
                if (emuart == null || emuart.haveUE == false) goto btn_autoupdate1_Click_EXIT2;    //串口连接失败
                                                                                                   //（3.2）显示区初始化
                                                                                                   //fmain.lbl_mainstatus.Text = "";   //左下提示区
                                                                                                   //txtShow1("");     //右侧更新提示区  
                                                                                                   //（3.3）Hex文件选择成功、串口选择成功则进行自动更新操作//右下提示区
                update_old = new Update_old(hex_old.getHexList());    //新的更新数据列表
                try
                {
                    //（3.3.1）通过串口向MCU发送开始更新提示startUpdate,即11, update;
                    if (!(emuart.send(startUpdate, out bRet, 300, 2) && bRet != null
                        && Encoding.Default.GetString(bRet) == "Start Update")) goto btn_autoUpdate1_Click_EXIT8;
                    //fmain.lbl_mainstatus.Text = "运行状态：收到UE握手信息，将开始程序更新操作...";      //底部提示
                    //txtShow1("运行状态：收到UE握手信息，将开始程序更新操作...\r\n");                    //右侧更新提示区  
                    //（3.3.2）更新操作初始化
                    sum = update_old.getFrameNum();      //sum←待发送的总帧数
                    reStartFrame[0] = 0x04;          //返回帧的帧头reStartFrame[0]←0x04
                                                     //（3.3.3）发送第一帧数据，需等待较长时间
                    for (int i = update_old.getCurCount(); i < sum; i++)
                    {
                        data = update_old.getNextFrame();    //data←一帧数据
                        if (i == 0) { Array.Copy(data, 1, reStartFrame, 1, 2); }; // 若是第0帧data变动
                                                                                  //第26帧做特殊处理，防止延迟
                        if (i == 26)
                        {
                            int aaa = 10;
                        }
                        //发送数据，并等待接收返回信息
                        //(几种错误情况)
                        if (!emuart.send(data, out bRet, 500, 2)) goto btn_autoUpdate1_Click_EXIT9;   //未正确返回信息
                        if (bRet[0] == (byte)2 && bRet[1] != 0) goto btn_autoUpdate1_Click_EXIT10;  //UE接收数据帧出错
                        if ((bRet[0] == 1) && ((int)bRet[2] * 256 + bRet[1] != i)) goto btn_autoUpdate1_Click_EXIT11;  //UE接收到的帧数有误
                                                                                                                       //（正确情况）进度条显示更新进度                      
                                                                                                                       //this.prg_update1.Value = update_old.getSendCount() * 100 / sum;     //进度条显示       
                                                                                                                       //this.lbl_progressbar1.Text = update_old.getSendCount() * 100 / sum + "%";//进度条百分比显示 
                                                                                                                       //this.lbl_progressbar1.Refresh();
                                                                                                                       //成功提示
                        txtShow("当前第" + (i + 1).ToString() + "/" + sum.ToString() + "帧  " + bRet[0].ToString());     //右侧更新提示区  

                    }
                    //（3.4）程序更新成功
                    goto btn_autoupdate1_Click_EXIT4;
                }
                catch (Exception ex)
                {
                    //fmain.lbl_mainstatus.Text = "运行状态：系统异常退出" + ex;   //底部提示
                    //txtShow1("系统异常退出\r\n" + ex);     //右侧更新提示区  
                    goto btn_autoUpdate1_Click_EXIT7;
                }
            }
        //（4）退出区
        //（4.1）退出函数
        btn_autoupdate1_Click_EXIT:
            return retVal;

        //（4.2）Hex文件未选择
        btn_autoupdate1_Click_EXIT1:
            //fmain.lbl_mainstatus.Text = "运行状态：Hex文件未选择";   //底部提示
            goto btn_autoupdate1_Click_EXIT;

        //（4.3）未连接设备
        btn_autoupdate1_Click_EXIT2:
            //fmain.lbl_mainstatus.Text = "运行状态：未连接设备，请点击“重新连接”";   //底部提示
            goto btn_autoupdate1_Click_EXIT;

        //（4.4）程序整体更新成功
        btn_autoupdate1_Click_EXIT3:
            retVal = true;
            //fmain.lbl_mainstatus.Text = "运行状态：程序整体更新成功";   //底部提示
            //txtShow1("程序整体更新成功\r\n");     //右侧更新提示区  
            //this.prg_update1.Value = 100;
            //this.lbl_progressbar1.Text = "100%";
            //this.lbl_progressbar1.Refresh();
            goto btn_autoupdate1_Click_EXIT;

        //（4.5）（VA.10之前）程序更新成功
        btn_autoupdate1_Click_EXIT4:
            retVal = true;
            //fmain.lbl_mainstatus.Text = "运行状态：程序更新成功";   //底部提示
            //txtShow1("程序更新成功！\r\n");     //右侧更新提示区  
            //this.prg_update1.Value = 100;
            goto btn_autoUpdate1_Click_EXIT7;

        //（4.6）未接收到终端返回数据
        btn_autoupdate1_Click_EXIT5:
            //txtShow1("错误提示：未接收到终端返回数据\r\n");     //右侧更新提示区  
            goto btn_autoupdate1_Click_EXIT;

        //（4.7）接收到的更新返回数据异常
        btn_autoupdate1_Click_EXIT6:
            //txtShow1("错误提示：接收到的更新返回数据异常\r\n");     //右侧更新提示区  
            goto btn_autoupdate1_Click_EXIT;

        //（4.8）（VA.10之前）程序更新操作结束，重新允许导入新的Hex文件、切换更新方式、重连串口等操作
        btn_autoUpdate1_Click_EXIT7:
            //this.btn_fileopen1.Enabled = true;
            //if (flag != 1) this.btn_autoupdate1.Enabled = true;
            System.Threading.Thread.Sleep(100);
            return retVal;

        //以下都是VA.10版本之前的更新错误处理
        //（4.9）与UE握手失败
        btn_autoUpdate1_Click_EXIT8:
            //txtShow1("错误提示1：与UE握手失败！\r\n");     //右侧更新提示区  
            flag = 1;    //更新失败
            goto btn_autoUpdate1_Click_EXIT7;

        //（4.10）更新过程未收到返回信息
        btn_autoUpdate1_Click_EXIT9:
            //txtShow1("错误提示2：更新过程未收到返回信息！\r\n");     //右侧更新提示区  
            flag = 1;    //更新失败
            goto btn_autoUpdate1_Click_EXIT7;

        //（4.11）UE告知接收数据帧有误
        btn_autoUpdate1_Click_EXIT10:
            //txtShow1("错误提示3：UE告知接收数据帧有误！\r\n");     //右侧更新提示区  
            flag = 1;    //更新失败
            goto btn_autoUpdate1_Click_EXIT7;

        //（4.12）UE返回的帧数不对
        btn_autoUpdate1_Click_EXIT11:
            //txtShow1("错误提示4：UE返回的帧数不对！(" + ((int)bRet[2] * 256 + bRet[1]).ToString() + ")\r\n");//右侧更新提示区
            flag = 1;    //更新失败
            goto btn_autoUpdate1_Click_EXIT7;
        }


        //======================================================================
        //函数名称：Add_Internal_Software
        //函数返回：无
        //参数说明：无
        //功能概要：添加内部外接软件
        //======================================================================
        public void Add_Internal_Software(ref Process SerialPort, string FileName)
        {
            //【20200529 1/5】 新增内部外接软件功能，方法见【4.07】。
            SerialPort = new Process();
            SerialPort.StartInfo.FileName = FileName;
            try
            {
                SerialPort.Start();
            }
            catch
            {
                MessageBox.Show(null, "未有该功能的独立功能软件，请按照readme中步骤操作", "内部外接软件警告");
                return;
            }
            finally
            {

            }
        }
        //======================================================================
        //函数名称：bytesToStruct
        //函数返回：byte数组转换为对应的结构体
        //参数说明：bytes:字节数组;type:结构体类型
        //功能概要：将byte字节数组数据转换为对应的结构体数据
        //======================================================================
        public static object bytesToStruct(byte[] bytes, Type type)
        {
            //（1）变量声明
            int size;
            object obj;
            IntPtr structPtr;

            size = Marshal.SizeOf(type);
            //（2）判断字节长度
            if (size > bytes.Length) return null;
            //（3）分配结构体内存空间
            structPtr = Marshal.AllocHGlobal(size);
            //（4）将byte数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //（5）将内存空间转换为目标结构体
            obj = Marshal.PtrToStructure(structPtr, type);
            //（6）释放内存空间
            Marshal.FreeHGlobal(structPtr);

            return obj;
        }
        //复制KDS工程文件夹
        public static void CopyDirectory(string srcPath, string destPath)
        {
            try
            {
                //若无目标文件夹则创建
                System.IO.Directory.CreateDirectory(destPath);
                //获取源文件夹
                DirectoryInfo dir = new DirectoryInfo(srcPath);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //获取目录下（不包含子目录）的文件和子目录
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)     //判断是否文件夹
                    {
                        if (!Directory.Exists(destPath + "\\" + i.Name))
                        {
                            Directory.CreateDirectory(destPath + "\\" + i.Name);   //目标目录下不存在此文件夹即创建子文件夹
                        }
                        CopyDirectory(i.FullName, destPath + "\\" + i.Name);    //递归调用复制子文件夹
                    }
                    else
                    {
                        FileInfo file = i as FileInfo;
                        if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                            continue;
                        if (File.Exists(destPath + "\\" + file.Name))
                        {
                            FileInfo newFile = new System.IO.FileInfo(file.FullName);
                            FileInfo oldFile = new System.IO.FileInfo(destPath + "\\" + file.Name);
                            if (DateTime.Compare(newFile.LastWriteTime, oldFile.LastWriteTime) <= 0)
                                continue;
                        }
                        file.CopyTo(destPath + "\\" + file.Name, true);
                    }
                }
                //获得备份文件夹路径
                DirectoryInfo folder2 = new DirectoryInfo(destPath);
                //删除目标文件夹中多余的文件
                foreach (FileInfo file in folder2.GetFiles())
                {
                    if (!File.Exists(srcPath + "\\" + file.Name))
                        File.Delete(file.FullName);
                }
                foreach (DirectoryInfo dir2 in folder2.GetDirectories())
                {
                    if (!Directory.Exists(srcPath + "\\" + dir2.Name))
                        Directory.Delete(dir2.FullName, true);
                }
            }
            catch
            {
                throw;
            }
        }
        /// <summary>
        /// 当属性ContextString的值发生更改时调用
        /// 函数功能：若OnMyValueChanged委托被注册，则触发
        /// </summary>
        /// <param name="text"></param>
        private void WhenMyValueChange(string text)
        {
            if (OnMyValueChanged != null)
            {
                OnMyValueChanged(text);
            }

        }

        /// <summary>移除指定路径下的文件 【GZF】</summary>    
        /// <param name="file">文件的路径</param>
        public void removeFile(string file)
        {
            if (File.Exists(file))
            {
                File.Delete(file);
            }
        }

        /// <summary> 从Access表DataBaseSetting.db中读取MCU信息</summary>
        //private bool LoadMCUInfo()
        //{
        //    XDocument xMCUSettings = null;
        //    try
        //    {
        //        xMCUSettings = XDocument.Load(Globaldefine.exePath + @"Config\MCUSettings.xml");
        //    }
        //    catch { return false; }
        //    XElement xMCU = xMCUSettings.Element("MCUSettings").Element("MCU");
        //    strMCUName = xMCU.Attribute("MCUName").Value;
        //    strMCUType = xMCU.Element("MCUType").Value;
        //    strCCompile = xMCU.Element("gccTool").Value;
        //    strArTool = xMCU.Element("arTool").Value;
        //    strAssem = xMCU.Element("asTool").Value;
        //    strLinkerTool = xMCU.Element("ldTool").Value;
        //    strObjcopyTool = xMCU.Element("objCopyTo").Value;
        //    strObjdumpTool = xMCU.Element("objDumpTo").Value;
        //    strMakeTool = xMCU.Element("makeTool").Value;
        //    strNmTool = xMCU.Element("nmTool").Value;
        //    strHWBase = xMCU.Element("hardwareBase").Value;
        //    RAMStartAddr = xMCU.Element("RAMStartAddr").Value;
        //    RAMSize = xMCU.Element("RAMSize").Value;
        //    FlashStartAddr = xMCU.Element("FlashStartAddr").Value;
        //    FlashSize = xMCU.Element("FlashSize").Value;
        //    INTVectorStartAddr = xMCU.Element("INTVector").Value;
        //    PageStartAddr = xMCU.Element("pageStartAddr").Value;
        //    PageSize = xMCU.Element("pageSize").Value;
        //    PageCount = xMCU.Element("pageCount").Value;
        //    StakAddr = xMCU.Element("stackAddr").Value;
        //    FlashEraseStartAddr = xMCU.Element("flashEraseStartAddr").Value;
        //    CodeStartAddr = xMCU.Element("codeStartAddr").Value;
        //    CodeSize = xMCU.Element("codeSize").Value;
        //    return true;
        //}

        /// <summary>编译MCU程序</summary>
        private void Compile32Programmer()
        {
            string strMakefileHexPath = string.Empty;

            strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
            removeFile(strMakefileHexPath + @"\easily.hex");
            Process p = new Process();
            //Process类有一个StartInfo属性，这个是ProcessStartInfo类，包括了一些属性和方法，
            //设定程序名
            p.StartInfo.FileName = "cmd.exe";
            //关闭Shell的使用
            p.StartInfo.UseShellExecute = false;
            //重定向标准输入
            p.StartInfo.RedirectStandardInput = true;
            //重定向标准输出
            p.StartInfo.RedirectStandardOutput = true;
            //重定向错误输出
            p.StartInfo.RedirectStandardError = true;
            //设置不显示窗口
            p.StartInfo.CreateNoWindow = true;

            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);

            //上面几个属性的设置是比较关键的一步。
            p.Start();
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            //输入要执行的命令
            p.StandardInput.WriteLine(strMakefileHexPath.Substring(0, 2));//20160513 取出盘符，并切换到安装盘，在xp下无法直接切换到另一个盘的目录
            p.StandardInput.WriteLine("cd " + strMakefileHexPath);
            p.StandardInput.WriteLine("make all&exit");
            //string strRstComplier = p.StandardOutput.ReadToEnd();
            //无限等待关联进程的退出
            //p.WaitForExit();
            p.Close();//结束进程------20151018修改
            p.Dispose();
        }

        private void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                // 4. 异步调用，需要invoke  
                this.Invoke(ReadStdOutput, new object[] { e.Data });
            }
        }

        private void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
            {
                this.Invoke(ReadErrOutput, new object[] { e.Data });
            }
        }
        private void ReadStdOutputAction(string result)
        {
            ConsoleForm.txt_info.AppendText(result + "\r\n");
            if (result.Contains("Finished building: easily.hex"))
            {
                ConsoleForm.txt_info.SelectionColor = Color.Green;
                ConsoleForm.txt_info.AppendText("编译成功！\r\n");
                tlbl_status.Text = "编译成功";
            }
        }

        private void ReadErrOutputAction(string result)
        {
            if (result.Contains("error"))
            {
                ConsoleForm.txt_info.AppendText(result + "\r\n");
                ConsoleForm.txt_info.SelectionColor = Color.Red;
                ConsoleForm.txt_info.AppendText("发现错误，编译失败！" + "\r\n");
            }
        }

        //新建程序("GM"-图形化主程序)
        private bool CreateProgrammer(ProgrammerType TypeOfProgrammer)
        {
            this.panel1.Visible = false;
            //MDIParentFrame.InterruptSet = string.Empty;//清中断设置信息
            string programmerInfo = string.Empty;
            string IntNum = string.Empty;
            SubFuncType TypeOfSubFunc = SubFuncType.NULL;
            int pos = -1;
            //若程序类型合法
            if (TypeOfProgrammer != ProgrammerType.NULL)
            {
                if (TypeOfProgrammer == ProgrammerType.GraphicMain)   //创建主程序
                {
                    //====判断窗口是否已有工程20160406=======
                    int i;
                    for (i = 0; i < frmGraphicFlowArray.Count; i++)
                    {
                        if (((frmGraphicProgrammer)frmGraphicFlowArray[i]).ProgrammerType == ProgrammerDocumentType.MainFun)
                        {
                            break;
                        }
                    }
                    if (i < frmGraphicFlowArray.Count)//说明图形化编程窗口已有主程序，不能再创建新的工程
                    {
                        MessageBox.Show("图形化编程窗口已有有一个工程，请关闭当前工程再创建新工程！！！");
                        return true;

                    }
                    //=================================
                    SaveFileDialog OF = new SaveFileDialog();
                    OF.Title = "设置新建主程序工程文件名和路径";
                    OF.DefaultExt = "prj";
                    OF.Filter = "主程序工程文件|*.prj";
                    //OF.InitialDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EasilyProjects");
                    if (OF.ShowDialog() == DialogResult.OK)
                    {
                        programmerInfo = OF.FileName;
                        pos = programmerInfo.LastIndexOf('\\');
                        ProjectPath = programmerInfo.Substring(0, pos + 1);//路径
                        ProjectName = programmerInfo.Substring(pos + 1, programmerInfo.Length - pos - 1);//工程名
                    }
                    else
                    {
                        return true;
                    }
                }
                //创建面板
                this.dockPanel1.DocumentStyle = DocumentStyle.DockingSdi;
                this.dockPanel1.ActiveDocumentChanged += new EventHandler(dockPanel1_ActiveDocumentChanged);
                //创建图形化编程的树形视图窗口、变量设置窗口和C代码窗口
                if (this.AlreadyCreateProgrammer == false)
                {
                    IconBoxOfForm = new frmIconBox();   //创建树形图标控件箱窗口
                    CodeOfForm = new frmGraphicCode();  //创建程序代码窗口
                    if (ConsoleForm == null)
                        ConsoleForm = new frmConsole();     //创建信息输出窗口
                    this.dockPanel1.DockRightPortion = 0.3;//[2018]设置靠右的控件占整个面板的比例0.36

                    //设置窗体停靠位置
                    IconBoxOfForm.Show(dockPanel1, DockState.DockLeft);
                    CodeOfForm.Show(dockPanel1, DockState.DockRight);
                    ConsoleForm.Show(dockPanel1, DockState.DockBottom);
                    this.AlreadyCreateProgrammer = true;
                }

                GraphicProgrammerOfForm = new frmGraphicProgrammer();
                ActivedrmGraphicFlow = GraphicProgrammerOfForm;
                //[2021/1/31] 未有工程前不可使用配置终端 此处新建工程可以打开
                this.配置硬件ToolStripMenuItem.Enabled = true;
                
                //[2021/1/31] 未有工程前不可使用串口更新 此处新建工程可以打开
                this.toolStripMenuItemWrite2MCU.Enabled = true;
                //图形化拖拽窗体停靠位置
                ActivedrmGraphicFlow.Show(this.dockPanel1, DockState.Document);
                //[20210511]设置窗体停靠位置
                
                //主程序设计面板
                if (TypeOfProgrammer == ProgrammerType.GraphicMain)
                {
                    pos = programmerInfo.LastIndexOf('\\');
                    //GraphicProgrammerOfForm.ProgrammerPath = programmerInfo.Substring(0, pos + 1);
                    //GraphicProgrammerOfForm.ProgrammerName = "main.dat";
                    //GraphicProgrammerOfForm.TabText = (/*GraphicFlowfrm.ProgrammerPath + */GraphicProgrammerOfForm.ProgrammerName);
                    ActivedrmGraphicFlow.ProgrammerType = ProgrammerDocumentType.MainFun;
                    // MessageBox.Show("将图标控件箱!"); // 在此未暂停控件箱第四项叶子节点会消失
                }                                        //原因在dockPanel1_ActiveDocumentChanged事件中清除
                //子程序设计面板
                else if (TypeOfProgrammer == ProgrammerType.GraphicSub)
                {
                    ActivedrmGraphicFlow.ProgrammerType = ProgrammerDocumentType.SubFun;
                    if (TypeOfSubFunc == SubFuncType.GeneralSubFunc)
                    {
                        ActivedrmGraphicFlow.TypeOfSubFunction = SubFunctionType.GeneralSubFunction;
                        //记录主程序名和路径
                        pos = programmerInfo.LastIndexOf('\\');
                        ActivedrmGraphicFlow.ProgrammerPath = programmerInfo.Substring(0, pos + 1);
                        ActivedrmGraphicFlow.ProgrammerName = programmerInfo.Substring(pos + 1, programmerInfo.Length - pos - 1);
                        ActivedrmGraphicFlow.TabText = (/*GraphicFlowfrm.ProgrammerPath + */ActivedrmGraphicFlow.ProgrammerName);
                    }
                    else if (TypeOfSubFunc == SubFuncType.IntSubFunc)
                    {
                        ActivedrmGraphicFlow.TypeOfSubFunction = SubFunctionType.IntSubFunction;
                        ActivedrmGraphicFlow.IntSubFuncNum = IntNum;
                        //记录主程序名和路径
                        pos = programmerInfo.LastIndexOf('\\');
                        ActivedrmGraphicFlow.ProgrammerPath = programmerInfo.Substring(0, pos + 1);
                        ActivedrmGraphicFlow.ProgrammerName = programmerInfo.Substring(pos + 1, programmerInfo.Length - pos - 1);
                        ActivedrmGraphicFlow.TabText = (/*GraphicFlowfrm.ProgrammerPath + */ActivedrmGraphicFlow.ProgrammerName);
                    }
                }
                ActivedrmGraphicFlow.SaveCodeOfFunc(Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source\07_AppPrg");
                //添加窗体到数组中
                frmGraphicFlowArray.Add(ActivedrmGraphicFlow);

                //当前工程是图形化编程工程
                this.CompileType = CompileDocumentType.CompileGraphics;

                if (TypeOfProgrammer == ProgrammerType.GraphicSub)
                {
                }

                else if (TypeOfProgrammer == ProgrammerType.GraphicMain)
                {
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        //打开程序   IsSubSave2Main=true 表示添加子程序, IsSubSave2Main=false 打开不添加到主程序
        private bool OpenProgrammer(ProgrammerType TypeOfProgrammer, bool IsSubSave2Main)
        {

            this.panel1.Visible = false; //关闭启动时的图片

            if (TypeOfProgrammer != ProgrammerType.NULL)
            {
                if (TypeOfProgrammer == ProgrammerType.GraphicMain)//打开主程序
                {
                    //====判断是否已有工程被打开=======
                    int i;
                    for (i = 0; i < frmGraphicFlowArray.Count; i++)
                    {
                        if (((frmGraphicProgrammer)frmGraphicFlowArray[i]).ProgrammerType == ProgrammerDocumentType.MainFun)
                        {
                            break;
                        }
                    }
                    if (i < frmGraphicFlowArray.Count)//说明已有主程序，不能再打开另一个主程序
                    {
                        MessageBox.Show("图形化编程窗口不能同时打开多个工程！！！");
                        return true;

                    }
                    //=================================
                    int pos = -1;
                    OpenFileDialog OF = new OpenFileDialog();
                    OF.Title = "打开工程文件";
                    OF.Filter = "工程文件|*.prj";
                    OF.DefaultExt = "prj";
                    //[2021/3/17] 每次打开工程都能定位到指定文件夹
                    //OF.InitialDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EasilyProjects");
                    if (OF.ShowDialog() == DialogResult.OK)
                    {
                        //记录当前路径
                        pos = OF.FileName.LastIndexOf('\\');
                        string path = OF.FileName.Substring(0, OF.FileName.LastIndexOf('\\') + 1);
                        ProjectPath = path;
                        ProjectName = OF.FileName.Substring(pos + 1, OF.FileName.Length - pos - 1);

                        //创建面板
                        this.dockPanel1.DocumentStyle = DocumentStyle.DockingSdi;
                        this.dockPanel1.ActiveDocumentChanged += new EventHandler(dockPanel1_ActiveDocumentChanged);//包含生成子程序控件
                        //创建图形化编程的树形视图窗口、变量设置窗口和C代码窗口
                        //this.bg.Visible = false;//隐藏背景
                        this.bg.Visible = true;// 背景
                        if (this.AlreadyCreateProgrammer == false)
                        {
                            IconBoxOfForm = new frmIconBox();   //创建树形图标控件箱窗口
                            CodeOfForm = new frmGraphicCode();  //创建程序代码窗口
                            if (ConsoleForm == null)
                                ConsoleForm = new frmConsole();     //创建信息输出窗口
                            this.dockPanel1.DockRightPortion = 0.3;//[2018]设置靠右的控件占整个面板的比例0.36
                            IconBoxOfForm.Show(dockPanel1, DockState.DockLeft);    //停靠在窗体左侧
                            CodeOfForm.Show(dockPanel1, DockState.DockRight);      //停靠在窗体右侧
                            ConsoleForm.Show(dockPanel1, DockState.DockBottom);    //停靠在窗体底部
                            this.AlreadyCreateProgrammer = true;
                        }
                        GraphicProgrammerOfForm = new frmGraphicProgrammer();
                        //图形化编程面板
                        
                        ActivedrmGraphicFlow = GraphicProgrammerOfForm;
                        ActivedrmGraphicFlow.Show(this.dockPanel1, DockState.Document);//执行到此，形成代码20151220
                        //[2021/1/31] 未有工程前不可使用配置终端 此处打开工程可以使用
                        this.配置硬件ToolStripMenuItem.Enabled = true;
                        
                        //[2021/3/9] 未有工程前不可使用串口更新 此处打开工程可以使用
                        this.toolStripMenuItemWrite2MCU.Enabled = true;

                        //将文件中的控件节点信息保存到IconGeneralArr、IconGdnJudgeArr等数组中
                        int retVal = ActivedrmGraphicFlow.OpenPro(ProjectPath + "\\" + ProjectName);
                        if (retVal == 0)
                        {
                            if (IsAdvanceMode == false)
                            {

                            }

                            ActivedrmGraphicFlow.Activate(); //激活主程序
                            ActivedrmGraphicFlow.CreateCode();
                            frmGraphicFlowArray.Add(ActivedrmGraphicFlow);
                            ActivedrmGraphicFlow.SaveCodeOfFunc(Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source\07_AppPrg");
                            //当前工程是图形化编程工程
                            this.CompileType = CompileDocumentType.CompileGraphics;
                            //【2021/3/11】实例化配置窗体
                            formHard = new frmConfigHardCon(true);
                        }
                        //高级模式下编辑过的工程
                        else if (retVal == 1)
                        {
                            if (IsAdvanceMode == false)
                            {
                                MessageBox.Show("当前模式下不能打开本工程！");
                            }
                            if (ActivedrmGraphicFlow != null)
                                ActivedrmGraphicFlow.IsHidden = true;
                            if (IconBoxOfForm != null) IconBoxOfForm.IsHidden = true;
                            dockPanel1.DockTopPortion = 0.8;
                            if (CodeOfForm != null)
                            {
                                //代码可编写
                                //CodeOfForm.Show(dockPanel1, DockState.DockTop);
                                CodeOfForm.setReadOnly(false);
                                CodeOfForm.addRightClick();
                            }
                            //当前工程是C语言编程工程
                            this.CompileType = CompileDocumentType.CompileCode;
                        }


                    }
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>保存工程文件，调用SavePro</summary>
        private void SaveProgrammerFile()
        {
            int i, mainNum;
            mainNum = -1;
            if (this.CompileType == CompileDocumentType.CompileGraphics)
            {
                for (i = 0; i < frmGraphicFlowArray.Count; i++)
                {
                    if (((frmGraphicProgrammer)frmGraphicFlowArray[i]).ProgrammerType == ProgrammerDocumentType.MainFun)
                    {
                        mainNum = i;
                        break;
                    }
                }
                //当前工程中有主程序
                if (i < frmGraphicFlowArray.Count)
                {
                    //主程序未设置路径
                    //记录工程路径和工程名
                    if (ProjectPath == "")
                    {
                        SaveFileDialog sf = new SaveFileDialog();
                        sf.DefaultExt = "prj";
                        sf.Filter = "工程文件|*.prj";
                        sf.Title = "保存工程至";
                        if (sf.ShowDialog() == DialogResult.OK)
                        {
                            //记录主程序名和路径
                            int pos = sf.FileName.LastIndexOf('\\');
                            ProjectPath = sf.FileName.Substring(0, pos + 1);
                            ProjectName = sf.FileName.Substring(pos + 1, sf.FileName.Length - pos - 1);
                            ((frmGraphicProgrammer)frmGraphicFlowArray[mainNum]).ProgrammerPath = sf.FileName.Substring(0, pos + 1);
                        }
                    }
                    ((frmGraphicProgrammer)frmGraphicFlowArray[mainNum]).SavePro(ProjectPath + "\\" + ProjectName);
                }
            }
        }
        private void CloseAllProgrammer()
        {
            //int i;

            if (this.CompileType == CompileDocumentType.CompileGraphics)
            {
                if (ModifyProgrammer)
                {
                    if (MessageBox.Show("是否保存所做的修改？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                        == DialogResult.Yes)
                    {
                        this.SaveProgrammerFile();
                    }
                    ModifyProgrammer = false;
                }
                foreach (frmGraphicProgrammer f in frmGraphicFlowArray)
                {
                    f.Dispose();
                    f.Close();
                }
                frmGraphicFlowArray.Clear();
                if (this.AlreadyCreateProgrammer)
                {
                    //图形化编程树形视图窗口
                    IconBoxOfForm.Dispose();
                    IconBoxOfForm.Close();
                    //图形化编程C代码窗口
                    CodeOfForm.Dispose();
                    CodeOfForm.Close();
                    //信息输出窗口窗口
                    ConsoleForm.Dispose();
                    ConsoleForm.Close();
                    IconBoxOfForm = null;
                    CodeOfForm = null;
                    ConsoleForm = null;
                    this.AlreadyCreateProgrammer = false;
                }
            }
            //[2021/4/13]hsc-图标放大 更改为0.9f
            Globaldefine.DotSize = 0.9F;//160406要与Globaldefine.cs中全局参数初始化定义一致，否则再次打开图形图标大小会变化

            //  public static float DotSize = 0.7F;//控件连接点大小 20160317
        }

        //通过串口连接GEC设备
        public bool connectGEC()
        {
            //（1）变量声明
            int ret;            //返回值
            string com = "";    //串口信息
            string sTemp = "";
            byte[] recv = null;//保存串口接收信息
            byte[] shake = { (byte)10, (byte)'s', (byte)'h', (byte)'a', (byte)'k', (byte)'e' }; //与终端握手帧数据
            bool retVal = false;

            //（3）重新遍历串口，寻找终端
            if (emuart._Uartport != null)
            {
                //【20191024】  (3.1)让耗时操作做完，如果不做完耗时操作，无法进行下面的事件，且界面不响应
                Application.DoEvents();
                emuart._Uartport.Close();
                emuart._Uartport.Dispose();
                //【20200401】 姜家乐 增加延时函数
                Thread.Sleep(10);
            }
            //Thread.Sleep(100);   //等待串口关闭
            //emuart.RawDataReceivedEvent -= new EMUART.RawDataReceived(DataRecv);//解除事件绑定的方法，加快握手速度
            if (emuart != null) emuart = null;
            emuart = EMUART.getInstance();    //每次“重新连接”重新实例化
            tlbl_status.Text = "运行状态：正在连接GEC...正在查找匹配设备...";
            ret = emuart.findDevice(out com, 115200);  //寻找emuart设备
            tlbl_status.Text = "运行状态：正在连接GEC...尝试与匹配设备建立通信...";
            //（4）根据寻找串口的返回值确定执行下列分支
            //（4.1）如果连接终端的emuart失败，退出函数
            if (ret == 1) goto btn_uartcheck_Click_EXIT1;
            //（4.2）找到串口，没有找到UE，退出函数
            else if (ret == 2) goto btn_uartcheck_Click_EXIT2;
            //（4.3)如果找到串口与UE,向设备发送握手帧
            tlbl_status.Text = "运行状态：正在连接GEC...向该设备发送握手信息，准备接收设备返回消息...";
            emuart.bufferClear();   //清除接收数组缓冲区
            emuart.send(shake, out recv, 100, 3); //获得设备的信息在recv中
            tlbl_status.Text = "运行状态：正在连接GEC...正在处理设备返回信息...";     //底部提示
            if (recv == null) goto btn_uartcheck_Click_EXIT3;//未收到数据，退出              
            //（4.4)发送握手帧后，若收到设备返回数据，处理之
            //（4.4.1）如果终端的更新程序版本为VA.10以后的版本（通用于所有GEC芯片）
            //string aaa = System.Text.Encoding.Default.GetString(recv);
            int length1 = Marshal.SizeOf(typeof(shakeData));
            int length = Marshal.SizeOf(typeof(newshakeData));

            if (recv.Length == Marshal.SizeOf(typeof(shakeData)))
            {
                tlbl_status.Text = "运行状态：成功连接到GEC设备";     //底部提示
                softVersion = 2;  //表示终端更新程序为A.10之后的通用版本
                //byte数组转结构体
                shakedata = (shakeData)bytesToStruct(recv, typeof(shakeData));
                //获取握手帧数据
                uecomType = Encoding.Default.GetString(shakedata.uecomType).Replace("\0", "");
                mcuType = Encoding.Default.GetString(shakedata.mcuType).Replace("\0", "");
                //处理获得符合要求的mcuType
                mcuType = mcuType.Replace("[", "").Replace("]", "");
                //if (mcuType.Contains("KL36"))
                //    mcuType += "xxx4";
                uStartAds = shakedata.uStartAds;
                uCodeSize = shakedata.uCodeSize;
                replaceNum = shakedata.replaceNum;
                reserveNum = shakedata.reserveNum;
                //设置设备信息                   
                sTemp = com + "：" + uecomType + " " + mcuType;  //设备信息
            }
            else if (recv.Length == Marshal.SizeOf(typeof(newshakeData)))
            {

                softVersion = 2;  //表示终端更新程序为A.10之后的通用版本
                //byte数组转结构体
                try
                {
                    newshakedata = (newshakeData)bytesToStruct(recv, typeof(newshakeData));
                    //获取握手帧数据
                    uecomType = Encoding.Default.GetString(newshakedata.uecomType).Replace("\0", "");
                    mcuType = Encoding.Default.GetString(newshakedata.mcuType).Replace("\0", "").Replace(" ", "");
                    uStartAds = newshakedata.uStartAds;    //User程序起始地址
                    uCodeSize = newshakedata.uCodeSize;
                    replaceNum = newshakedata.replaceNum;
                    reserveNum = newshakedata.reserveNum;
                    //【20200715 1/2】 获取结构体中的BIOS版本信息
                    //biosVersion = Encoding.Default.GetString(newshakedata.BIOSVersion);
                    //sectorStart = uStartAds / uCodeSize;    //BIOS 中读取的用户程序扇区号
                }
                catch (Exception)
                {
                    throw;
                }
                //设置设备信息  
                //【20200715 2/2】 将版本信息显示出来 
                sTemp = com + "：" + " " + mcuType;  //设备信息
                //#region 记录设备信息，重新打开串口
                //PublicVar.g_SCIComNum = com;
                //#endregion


                //如果存在串口，则允许接收调试信息
                //if (this.emuart.haveUE)
                //{
                //    //绑定串口结束事件，处理串口调试信息
                //    emuart.RawDataReceivedEvent += new EMUART.RawDataReceived(DataRecv);
                //}

                //#region 退出前重新打开串口
                ////【20201014 1/2】重新连接GEC重新打开串口
                //if (PublicVar.g_SCIComNum == string.Empty)
                //    return true;
                //if (emuart._Uartport != null)
                //{
                //    Application.DoEvents();
                //    emuart._Uartport.Close();
                //    emuart._Uartport.Dispose();
                //    Thread.Sleep(10);
                //}
                //Thread.Sleep(50);
                ////emuart.RawDataReceivedEvent -= new EMUART.RawDataReceived(DataRecv);
                ////emuart = EMUART.getInstance();
                //emuart.bufferClear();
                ////if (emuart.reOpen(PublicVar.g_SCIComNum, 115200))
                ////    emuart.RawDataReceivedEvent += new EMUART.RawDataReceived(DataRecv);
                //#endregion
            }

            else if (recv.Length == Marshal.SizeOf(typeof(new2shakeData)))
            {

                softVersion = 2;  //表示终端更新程序为A.10之后的通用版本
                //byte数组转结构体
                try
                {
                    new2shakedata = (new2shakeData)bytesToStruct(recv, typeof(new2shakeData));
                    //获取握手帧数据
                    uecomType = Encoding.Default.GetString(new2shakedata.uecomType).Replace("\0", "");
                    mcuType = Encoding.Default.GetString(new2shakedata.mcuType).Replace("\0", "").Replace(" ", "");
                    uStartAds = new2shakedata.uStartAds;    //User程序起始地址
                    uCodeSize = new2shakedata.uCodeSize;
                    replaceNum = new2shakedata.replaceNum;
                    reserveNum = new2shakedata.reserveNum;
                    //【20200715 1/2】 获取结构体中的BIOS版本信息
                    //biosVersion = Encoding.Default.GetString(newshakedata.BIOSVersion);
                    //sectorStart = uStartAds / uCodeSize;    //BIOS 中读取的用户程序扇区号
                }
                catch (Exception)
                {
                    throw;
                }
                //设置设备信息  
                //【20200715 2/2】 将版本信息显示出来 
                sTemp = com + "：" + " " + mcuType;  //设备信息
                //#region 记录设备信息，重新打开串口
                //PublicVar.g_SCIComNum = com;
                //#endregion


                //如果存在串口，则允许接收调试信息
                //if (this.emuart.haveUE)
                //{
                //    //绑定串口结束事件，处理串口调试信息
                //    emuart.RawDataReceivedEvent += new EMUART.RawDataReceived(DataRecv);
                //}

                //#region 退出前重新打开串口
                ////【20201014 1/2】重新连接GEC重新打开串口
                //if (PublicVar.g_SCIComNum == string.Empty)
                //    return true;
                //if (emuart._Uartport != null)
                //{
                //    Application.DoEvents();
                //    emuart._Uartport.Close();
                //    emuart._Uartport.Dispose();
                //    Thread.Sleep(10);
                //}
                //Thread.Sleep(50);
                ////emuart.RawDataReceivedEvent -= new EMUART.RawDataReceived(DataRecv);
                ////emuart = EMUART.getInstance();
                //emuart.bufferClear();
                ////if (emuart.reOpen(PublicVar.g_SCIComNum, 115200))
                ////    emuart.RawDataReceivedEvent += new EMUART.RawDataReceived(DataRecv);
                //#endregion
            }



            //（4.4.2）如果终端的更新程序版本为VA.10及其以前的版本
            else if (System.Text.Encoding.Default.GetString(recv).Contains("shake:GEC-")
                || System.Text.Encoding.Default.GetString(recv).Contains("KL36"))
            {
                shakedata = (shakeData)bytesToStruct(recv, typeof(shakeData));
                mcuType = Encoding.Default.GetString(shakedata.mcuType).Replace("\0", "");
                //处理获得符合要求的mcuType
                mcuType = mcuType.Replace("[", "").Replace("]", "");
                softVersion = 1;   //表示终端更新程序为A.10及之前的版本
                sTemp = mcuType + "(" + com + ")";//设备信息
            }
            //（4.4.3）若收到错误返回信息，退出函数
            else goto btn_uartcheck_Click_EXIT3;
            retVal = true;
        //(5)退出区
        //(5.1)退出函数
        btn_uartcheck_Click_EXIT:
            return retVal;

        //(5.2)不存在可用串口
        btn_uartcheck_Click_EXIT1:
            goto btn_uartcheck_Click_EXIT;

        //(5.3)存在串口，但不存在emuar设备
        btn_uartcheck_Click_EXIT2:
            emuart.terminate(115200); //发送数据给终端设备，让终端设备清空其数据缓冲区
            goto btn_uartcheck_Click_EXIT;

        //(5.4)未收到返回信息或收到错误返回信息
        btn_uartcheck_Click_EXIT3:
            emuart.terminate(115200); //发送数据给终端设备，让终端设备清空其数据缓冲区
            goto btn_uartcheck_Click_EXIT;
        }


        private void txtShow(string str)
        {
            if (ConsoleForm != null)
                ConsoleForm.txt_info.AppendText(str + "\r\n");
            //ConsoleForm.txt_info.ScrollToCaret();   //移动到光标处
        }




        #endregion

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string outData = "";
            string showMsg = "";
            string hexFilePath = $@"{Globaldefine.exePath}\Project\{mcuType}\{textIDE}\BIOS.hex";
            string jlinkFilePath = $@"{Globaldefine.exePath}\Tool\JLink\bin\Jlink.exe";
            tlbl_status.Text = "              正 在 下 载，请 稍 候...！！！";
            string strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
            if (!File.Exists(strMakefileHexPath + @"\easily.hex"))
                toolStripMenuItemCompile_Click(sender, e);
            //this.Refresh(); //让上面的提示，立即显示qingshaoh
            using (Process p = new Process())
            {
                //Process类有一个StartInfo属性，这个是ProcessStartInfo类，包括了一些属性和方法，                
                p.StartInfo.FileName = jlinkFilePath;      //设定程序名   
                p.StartInfo.UseShellExecute = false;//关闭Shell的使用
                p.StartInfo.CreateNoWindow = true;  //设置不显示窗口                
                p.StartInfo.RedirectStandardInput = true;  //重定向标准输入                
                p.StartInfo.RedirectStandardOutput = true; //重定向标准输出                
                p.StartInfo.RedirectStandardError = true;  //重定向错误输出  

                p.OutputDataReceived += (sender2, e2) =>
                {
                    if (e2.Data != null)
                        outData += e2.Data.ToString() + "\r\n";
                };
                p.Start();
                p.BeginOutputReadLine();
                //烧录程序，并运行
                //当有一句指令执行失败就应该跳出
                p.StandardInput.WriteLine("connect");
                p.StandardInput.WriteLine();
                p.StandardInput.WriteLine("s");
                p.StandardInput.WriteLine();
                p.StandardInput.WriteLine("erase");
                p.StandardInput.WriteLine($"loadfile {hexFilePath}");
                p.StandardInput.WriteLine("r");
                p.StandardInput.WriteLine("g");
                p.StandardInput.WriteLine("qc");

                p.WaitForExit();   //等待程序退出

                if (outData == "")
                    showMsg = "下载失败：无信息返回！";
                else if (outData.Contains("Connecting to J-Link via USB...FAILED"))
                    showMsg = "下载失败：未连接SWD写入器，请连接后重试！";
                else if (outData.Contains("Writing target memory failed"))
                    showMsg = "下载失败：已连接SWD写入器，但未连接设备或选择的设备型号有误！";
                else
                    showMsg = "下载成功！";

                tlbl_status.Text = showMsg;
                MessageBox.Show(showMsg);

                p.Close();//结束进程------20151018修改
                p.Dispose();
            }
        }

        /// <summary>
        /// 点击后会显示帮助文档
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void helpToolStripButton_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = Globaldefine.exePath + "Resource\\usebook.txt";//文件地址
            //可以打开任意的文件类型，例如：txt，pdf，chm等文件
            process.StartInfo.Verb = "Open";
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
            process.Start();
        }

        /// <summary>
        /// 2021/01/27 新建包含内置三色灯案例的工程
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InnerLightoolStrip_Click(object sender, EventArgs e)
        {
            //新建相当于是打开已有的内置三色灯工程
            //if (!OpenProgrammer(ProgrammerType.GraphicMain, false))
            //{
            //    MessageBox.Show("打开主程序失败!");
            //}
            //但已有的OpenProgrammer并不适用，它会让用户自己选择工程文件
            //所以在其基础上修改成合适的OpenExistProgrammer函数
            if (!OpenExistProgrammer(ProgrammerType.GraphicMain, false,"innerlight"))
            {
                MessageBox.Show("新建项目工程-内置三色灯失败!");
            }
            else
                MessageBox.Show("项目工程已新建在" + Globaldefine.exePath + "AHLProjects文件夹下!" +
                    "\n请及时将该工程移出该目录！以防新安装后工程全部被覆盖！");
        }

        //打开程序   IsSubSave2Main=true 表示添加子程序, IsSubSave2Main=false 打开不添加到主程序
        private bool OpenExistProgrammer(ProgrammerType TypeOfProgrammer, bool IsSubSave2Main,String projectName)
        {
            this.panel1.Visible = false; //关闭启动时的图片

            if (TypeOfProgrammer != ProgrammerType.NULL)
            {
                if (TypeOfProgrammer == ProgrammerType.GraphicMain)//打开主程序
                {
                    //====判断是否已有工程被打开=======
                    int i;
                    for (i = 0; i < frmGraphicFlowArray.Count; i++)
                    {
                        if (((frmGraphicProgrammer)frmGraphicFlowArray[i]).ProgrammerType == ProgrammerDocumentType.MainFun)
                        {
                            break;
                        }
                    }
                    if (i < frmGraphicFlowArray.Count)//说明已有主程序，不能再打开另一个主程序
                    {
                        MessageBox.Show("图形化编程窗口不能同时打开多个工程！！！");
                        return true;

                    }
                    //=================================
                    //int pos = -1;
                    //OpenFileDialog OF = new OpenFileDialog();
                    //OF.Title = "打开工程文件";
                    //OF.Filter = "工程文件|*.prj";
                    //OF.DefaultExt = "prj";
                    //if (OF.ShowDialog() == DialogResult.OK)
                    //{
                    //记录当前路径
                    //pos = OF.FileName.LastIndexOf('\\');
                    //string path = OF.FileName.Substring(0, OF.FileName.LastIndexOf('\\') + 1);
                    //这里原本通过文件对话框打开工程文件
                    //而我们需要读取由04-Config被复制到\bin\Debug\Config文件夹下的innerlight.prj
                    //通过观察config.json的读取方式 可以获取到innerlight.prj文件的路径格式
                    //Globaldefine.exePath + @"Config\innerlight.prj"
                    //1、设置工程路径和工程名
                    //在bin\Debug文件夹下创建AHLProjects文件夹
                    //1.1 复制\bin\Debug\Config文件夹下的innerlight.prj至AHLProjects文件夹
                    //以免innerlight.prj被覆盖
                    int cnt = 1;//标记重复文件
                    string path = Globaldefine.exePath + @"\AHLProjects\"+projectName+".prj";//innerlight.prj文件的路径
                    //目录名、文件名、扩展名 用于重复文件命名
                    string directory = Path.GetDirectoryName(path);
                    string filename = Path.GetFileNameWithoutExtension(path);
                    string extension = Path.GetExtension(path);
                    string newPath = path;
                    while (File.Exists(newPath))
                    {
                        string newFilename = filename + "(" + cnt + ")" + extension;
                        newPath = Path.Combine(directory, newFilename);
                        cnt++;
                    }
                    if(File.Exists(Globaldefine.exePath + @"Config\"+projectName+".prj"))
                    {
                        File.Copy(Globaldefine.exePath + @"Config\" + projectName + ".prj", newPath);
                        ProjectPath = Path.GetDirectoryName(newPath);
                        ProjectName = Path.GetFileName(newPath);
                        //Console.WriteLine(ProjectPath);
                        //Console.WriteLine(ProjectName);
                        //2、创建面板
                        this.dockPanel1.DocumentStyle = DocumentStyle.DockingSdi;
                        this.dockPanel1.ActiveDocumentChanged += new EventHandler(dockPanel1_ActiveDocumentChanged);//包含生成子程序控件
                                                                                                                    //创建图形化编程的树形视图窗口、变量设置窗口和C代码窗口
                                                                                                                    //this.bg.Visible = false;//隐藏背景
                        this.bg.Visible = true;// 背景
                        if (this.AlreadyCreateProgrammer == false)
                        {
                            IconBoxOfForm = new frmIconBox();   //创建树形图标控件箱窗口
                            CodeOfForm = new frmGraphicCode();  //创建程序代码窗口
                            if(ConsoleForm==null)
                                ConsoleForm = new frmConsole();     //创建信息输出窗口
                            this.dockPanel1.DockRightPortion = 0.3;//[2018]设置靠右的控件占整个面板的比例0.36
                            IconBoxOfForm.Show(dockPanel1, DockState.DockLeft);    //停靠在窗体左侧
                            CodeOfForm.Show(dockPanel1, DockState.DockRight);      //停靠在窗体右侧
                            ConsoleForm.Show(dockPanel1, DockState.DockBottom);    //停靠在窗体底部
                            this.AlreadyCreateProgrammer = true;
                        }
                        GraphicProgrammerOfForm = new frmGraphicProgrammer();
                        
                        ActivedrmGraphicFlow = GraphicProgrammerOfForm;
                        ActivedrmGraphicFlow.Show(this.dockPanel1, DockState.Document);//执行到此，形成代码20151220
                        //[2021/1/31] 未有工程前不可使用配置终端 此处打开已有工程可以使用
                        this.配置硬件ToolStripMenuItem.Enabled = true;

                        //[2021/3/9] 未有工程前不可使用串口更新 此处打开已有工程可以使用
                        this.toolStripMenuItemWrite2MCU.Enabled = true;
                        //图形化编程面板
                        
                        //将文件中的控件节点信息保存到IconGeneralArr、IconGdnJudgeArr等数组中
                        //这里的路径要注意ProjectPath和ProjectName存储的具体格式是什么
                        //通过OpenProgrammer中对ProjectPath和ProjectName的输出测试 可以知道他们的格式是
                        //分别是F:\01-图形化\Projs\和innerlight.prj
                        int retVal = ActivedrmGraphicFlow.OpenPro(ProjectPath + "\\" + ProjectName);

                        if (retVal == 0)
                        {
                            if (IsAdvanceMode == false)
                            {

                            }

                            ActivedrmGraphicFlow.Activate(); //激活主程序
                            ActivedrmGraphicFlow.CreateCode();
                            frmGraphicFlowArray.Add(ActivedrmGraphicFlow);
                            ActivedrmGraphicFlow.SaveCodeOfFunc(Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE + @"\Source\07_AppPrg");
                            //当前工程是图形化编程工程
                            this.CompileType = CompileDocumentType.CompileGraphics;
                            //【2021/3/11】实例化配置窗体
                            formHard = new frmConfigHardCon(true);
                        }
                        //高级模式下编辑过的工程
                        else if (retVal == 1)
                        {
                            if (IsAdvanceMode == false)
                            {
                                MessageBox.Show("当前模式下不能打开本工程！");
                            }
                            if (ActivedrmGraphicFlow != null)
                                ActivedrmGraphicFlow.IsHidden = true;
                            if (IconBoxOfForm != null) IconBoxOfForm.IsHidden = true;
                            dockPanel1.DockTopPortion = 0.8;
                            if (CodeOfForm != null)
                            {
                                //代码可编写
                                //CodeOfForm.Show(dockPanel1, DockState.DockTop);
                                CodeOfForm.setReadOnly(false);
                                CodeOfForm.addRightClick();
                            }
                            //当前工程是C语言编程工程
                            this.CompileType = CompileDocumentType.CompileCode;
                        }

                    }
                    else
                    {
                        MessageBox.Show("基础工程已被删除！请重新安装Easily！");
                        return false;
                    }
                    //}
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        private void lineChart_Click(object sender, EventArgs e)
        {
            //新建一个折线图窗体
            frmLineChart lineChart = new frmLineChart();
            //this.Controls.Add(lineChart);
            lineChart.Show();
        }

        private void 配置终端使用说明ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //【20210327】 新建窗体存储textbox
            Form form = new Form()
            {
                Height = 350,
                Width = 900,
                Text = "配置终端使用说明"
            };
            string usingbook = File.ReadAllText(Globaldefine.exePath + @"Resource\配置终端使用说明.txt");
            RichTextBox textBox = new RichTextBox()
            {
                Text = usingbook,
                Dock = DockStyle.Fill,
                Font = new Font("宋体", 14)
            };
            form.Controls.Add(textBox);
            form.Show();
        }

        /// <summary>
        /// 打开AHLProjects文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripOpenDir_Click(object sender, EventArgs e)
        {
            string v_OpenFolderPath = Path.Combine(Globaldefine.exePath, "AHLProjects");
            Process.Start("explorer.exe", v_OpenFolderPath);
        }

        private void 搜索ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //[2021/5/6]如果不是高级模式 无法使用该功能
            if(!Globaldefine.FrmParent.IsAdvanceMode)
            {
                MessageBox.Show("请切换到高级模式下，再使用本功能！");
            }
        }

        private void test_Click(object sender, EventArgs e)
        {
            if(ConsoleForm==null)
                ConsoleForm = new frmConsole();
            panel1.Visible = false;
            ConsoleForm.txt_info.Focus();
            ConsoleForm.Show(dockPanel1,DockState.DockBottom);
            //（1）判断串口界面是否已经打开
            //【4.07 2/4】关闭其他进程，防止资源浪费
            if (SerialPort != null)
            {
                SerialPort = null;
            }
            txtShow("正在与终端UE建立连接...");
            if (!connectGEC())
            {
                MessageBox.Show("与UE通信失败");
                return;
            }
            else
            {
                txtShow("与终端UE连接成功！");
                //byte[] shake = { (byte)10, (byte)'s', (byte)'h', (byte)'a', (byte)'k', (byte)'e' };
                tlbl_status.Text = "              正 在 使用 串 口 下 载，请 稍 候...！！！";
                string strMakefileHexPath = Globaldefine.exePath + @"Resource";
                if (!File.Exists(strMakefileHexPath + @"\test.hex"))
                {
                    MessageBox.Show("未找到hex文件，请重新编译！");
                }
                if (openHex(strMakefileHexPath + @"\test.hex") && downloadHexByUart())
                {
                    ConsoleForm.txt_info.SelectionColor = Color.Green;
                    txtShow("测试程序已烧录！请观察现象是否与用户手册的指示一致！");
                    tlbl_status.Text = "              烧 录 成 功 ！！！";
                    //MessageBox.Show("烧录成功！");
                }
                else
                {
                    ConsoleForm.txt_info.SelectionColor = Color.Red;
                    txtShow("烧录失败，请检查串口线连接情况之后重试！");
                    tlbl_status.Text = "              烧 录 失 败 ！！！";
                    MessageBox.Show("烧录失败，请检查串口线连接情况之后重试！");
                }
                //烧录完成后 关闭串口
                if (emuart._Uartport != null)
                {
                    emuart._Uartport.Close();
                    emuart._Uartport.Dispose();
                }
            }
        }

        private void 有线更新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ConsoleForm == null)
            {
                ConsoleForm = new frmConsole();
                panel1.Visible = false;
                ConsoleForm.txt_info.Focus();
                ConsoleForm.Show(dockPanel1, DockState.DockBottom);
            }
            ConsoleForm.txt_info.Focus();
            //（1）判断串口界面是否已经打开
            //【4.07 2/4】关闭其他进程，防止资源浪费
            if (SerialPort != null)
            {
                SerialPort = null;
            }
            txtShow("正在与终端UE建立连接...");
            if (!connectGEC())
            {
                MessageBox.Show("与UE通信失败");
                return;
            }
            else
            {
                txtShow("与终端UE连接成功，已获取芯片信息！");
                //byte[] shake = { (byte)10, (byte)'s', (byte)'h', (byte)'a', (byte)'k', (byte)'e' };
                tlbl_status.Text = "              正 在 使用 串 口 下 载，请 稍 候...！！！";
                string strMakefileHexPath = Globaldefine.exePath + @"Project\" + mcuType + "\\" + textIDE;
                if (!File.Exists(strMakefileHexPath + @"\easily.hex"))
                {
                    MessageBox.Show("未找到hex文件，请重新编译！");
                }
                if (openHex(strMakefileHexPath + @"\easily.hex") && downloadHexByUart())
                {
                    ConsoleForm.txt_info.SelectionColor = Color.Green;
                    txtShow("烧录成功！");
                    tlbl_status.Text = "              烧 录 成 功 ！！！";
                    //MessageBox.Show("烧录成功！");
                }
                else
                {
                    ConsoleForm.txt_info.SelectionColor = Color.Red;
                    txtShow("烧录失败，请检查串口线连接情况之后重试！");
                    tlbl_status.Text = "              烧 录 失 败 ！！！";
                    MessageBox.Show("烧录失败，请检查串口线连接情况之后重试！");
                }
                //烧录完成后 关闭串口
                if (emuart._Uartport != null)
                {
                    emuart._Uartport.Close();
                    emuart._Uartport.Dispose();
                }
                //Thread.Sleep(10);   //等待串口关闭
            }
        }

        private void 网络工程WIFIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //新建相当于是打开已有的内置三色灯工程
            //if (!OpenProgrammer(ProgrammerType.GraphicMain, false))
            //{
            //    MessageBox.Show("打开主程序失败!");
            //}
            //但已有的OpenProgrammer并不适用，它会让用户自己选择工程文件
            //所以在其基础上修改成合适的OpenExistProgrammer函数
            if (!OpenExistProgrammer(ProgrammerType.GraphicMain, false,"innerWIFI"))
            {
                MessageBox.Show("新建项目工程-内置三色灯失败!");
            }
            else
                MessageBox.Show("项目工程已新建在" + Globaldefine.exePath + "AHLProjects文件夹下!" +
                    "\n请及时将该工程移出该目录！以防新安装后工程全部被覆盖！");
        }

        private void 无线更新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //（4）串口更新页面是否已打开
            if (mfrm_NBUpdate == null || mfrm_NBUpdate.IsDisposed)
            {
                //新建frm_update窗体
                mfrm_NBUpdate = new frm_NBUpdate();
                ////设置mfrm_update的父窗体为本窗体
                //mfrm_NBUpdate.MdiParent = this;
            }
            //（6）显示串口更新页面
            mfrm_NBUpdate.Hide();  //置顶显示
            mfrm_NBUpdate.Show();
        }

        // AI help
        private KimiHelper kimi_helper;
        private void KimiAI_Click(object sender, EventArgs e)
        {
            if (kimi_helper == null || kimi_helper.IsDisposed)
                kimi_helper = new KimiHelper();
            kimi_helper.Show();
        }
    }
}
